package com.cssw.fyzb.busi.api.acct;

import com.cssw.fyzb.busi.service.acct.AcctService;
import com.cssw.fyzb.busi.service.system.SysParamService;
import com.cssw.fyzb.busi.service.team.TeamService;
import com.cssw.fyzb.busi.service.user.UserService;
import com.cssw.fyzb.busi.util.BizUtil;
import com.cssw.fyzb.busi.util.Bizs;
import com.cssw.fyzb.busi.util.UuidUtil;
import com.cssw.fyzb.core.eao.acct.AcctLogEao;
import com.cssw.fyzb.core.exception.BizException;
import com.cssw.fyzb.core.model.dodb.*;
import com.cssw.fyzb.core.model.mos.UserMo;
import com.ydn.appserver.Action;
import com.ydn.appserver.Request;
import com.ydn.appserver.Response;
import com.ydn.appserver.annotations.Function;
import com.ydn.appserver.annotations.Parameter;
import com.ydn.appserver.annotations.Type;
import com.ydn.dbframe.plugin.activerecord.Db;
import com.ydn.simplelock.SimpleLock;
import com.ydn.simplelock.SimpleLockFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Date;

@Function(description = "转账", parameters = {
        @Parameter(name = "transferType", type = Type.String, description = "转账类型", required = true),
        @Parameter(name = "money", type = Type.String, description = "数量", required = true),
        @Parameter(name = "fromUserId", type = Type.String, description = "转出id", required = true),
        @Parameter(name = "toUserId", type = Type.String, description = "转入id", required = true),
        @Parameter(name = "tradePwd", type = Type.String, description = "交易密码", required = true),
        @Parameter(name = "remark", type = Type.String, description = "备注", required = false)
})
@Component
public class Transfer implements Action {

    private static final Logger logger = LoggerFactory.getLogger(ListAcctLog.class);

    @Autowired
    UserService userService;

    @Autowired
    AcctService acctService;

    @Autowired
    SimpleLockFactory simpleLockFactory;

    @Autowired
    SysParamService sysParamService;

    @Autowired
    AcctLogEao acctLogEao;

    @Autowired
    TeamService teamService;

    @Override
    public Response execute(Request request) throws Exception {
        if (true){
            return Response.fail("转账功能暂未开放");
        }

        String transferType = request.getString("transferType");
        BigDecimal money = new BigDecimal(request.getString("money"));
        Long fromUserId = request.getLong("fromUserId");
        Long toUserId = request.getLong("toUserId");
        String tradePwd = request.getString("tradePwd");
        String remark = request.getString("remark");
        SimpleLock fromLock = simpleLockFactory.getLock("USER_"+fromUserId);
        SimpleLock toLock = simpleLockFactory.getLock("USER_"+toUserId);
        try{
            fromLock.acquire();
            toLock.acquire();
            User user = userService.getById(fromUserId);
            if(user.getTradePwd()==null){
                return Response.fail("交易密码未设置");
            }
            user = userService.getByTradePwd(fromUserId, tradePwd);
            if(user==null){
                return Response.fail("交易密码不正确");
            }
            // 转账参数初始化
            //开始转账事务
            Db.tx(() -> {
                compareTeamNum(fromUserId, toUserId);

                Acct acct = acctService.queryAcctByUIdAndType(fromUserId, transferType);
                if (acct.getBalanceFee().compareTo(money) < 0){
                    BizUtil.exception(Bizs.ERROR_BALANCE_LESS);
                }

                SysParam sysParam = sysParamService.findByCode(SysParam.TRANSFER_HANDLE_FEE_RATIO);
                BigDecimal handleFeeRatio = new BigDecimal(sysParam.getParamValue());

                // 添加转账日志
                Long transferLogId = acctService.addTransferLog(transferType, fromUserId, toUserId, money, remark);
                UserMo fromUserMo = userService.findById(fromUserId);
                UserMo toUserMo = userService.findById(toUserId);
                // 减少余额
                acctService.minusBalance(fromUserId, transferType, money, transferLogId.toString(),  AcctTradeType.TRANSFER, BusiType.TRANSFER, "转账给"+toUserMo.getNickName());

                //需要扣除手续费
                BigDecimal addAmount = money.subtract(money.multiply(handleFeeRatio)).setScale(7);

                // 增加余额
                acctService.addBalance(toUserId, transferType, addAmount, transferLogId.toString(),
                        AcctTradeType.TRANSFER_RECE, BusiType.TRANSFER, "转账来自"+fromUserMo.getNickName());

                return true;
            });

            return Response.success("转账成功");
        }catch (Exception e){
            if (e instanceof BizException) {
                BizException se = (BizException) e;
                return Response.fail(se.getErrMsg(), se.getErrCode());
            }
            logger.error("", e);
            return Response.fail("转账失败");
        }finally {
            fromLock.release();
            toLock.release();
        }
    }

    private void compareTeamNum(Long fromUserId, Long toUserId){
        int fromTeamNum = teamService.getTeamNum(fromUserId);
        int toTeamNum = teamService.getTeamNum(toUserId);

        if (fromTeamNum > toTeamNum && fromTeamNum - toTeamNum >= 100){
            BizUtil.exception("团队人数不满足，操作失败！");
        } else if  (toTeamNum > fromTeamNum && toTeamNum - fromTeamNum >= 100){
            BizUtil.exception("团队人数不满足，操作失败！");
        }
    }
}
